package net.thxjj.adminServer.controller;

import cmcciot.onenet.nbapi.sdk.api.online.GetDeviceDataOpe;
import cmcciot.onenet.nbapi.sdk.api.online.GetDevicesOpe;
import cmcciot.onenet.nbapi.sdk.entity.GetDevice;
import cmcciot.onenet.nbapi.sdk.entity.GetDeviceData;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import net.thxjj.adminServer.controller.base.BaseController;
import net.thxjj.adminServer.entity.*;
import net.thxjj.adminServer.entity.onenet.OnetEvent;
import net.thxjj.adminServer.service.IDevOneNetLogService;
import net.thxjj.adminServer.service.IDeviceService;
import net.thxjj.adminServer.service.IProductService;
import net.thxjj.adminServer.util.DateUtil;
import net.thxjj.adminServer.util.ParameterMap;
import net.thxjj.adminServer.util.Tools;
import net.thxjj.adminServer.websocket.mq.JSONOneNet2DeviceUtil;
import net.thxjj.sitermodel.Device;
import net.thxjj.sitermodel.Product;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/onenet/update")
public class UserOneNetController extends BaseController {

    private Logger log = Logger.getLogger(this.getClass());

    private final static SimpleDateFormat sdfTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Autowired
    private IDeviceService deviceService;

    @Autowired
    private IDevOneNetLogService devOneNetLogService;

    @Autowired
    private IProductService iProductService;

    /**
     * 同步设备列表（NBIOT中移物联平台）
     * @return
     */
    @RequestMapping(value="/devices",method= RequestMethod.GET)
    @ResponseBody
    public Object getDevicesFromOneNet(){

        String prod_key = this.getParameterMap().getString("prod_key");
        if(Tools.isEmpty(prod_key)){
            return ResponseModel.getModel(ResultEnum.PARAMETER_EMPTY_ERROR,null);
        }

        Product product = iProductService.getProduct(prod_key);
        if(product==null || Tools.isEmpty(product.getApiKey())){
            return ResponseModel.getModel("查询数据为空",400,null);
        }

        int page = 1;
        boolean flag_end = false;

        List<Device> devicelist = new ArrayList<>();
        while (!flag_end){
            GetDevicesOpe deviceOpe = new GetDevicesOpe(product.getApiKey());
            GetDevice getDevice = new GetDevice(page);
            JSONObject data = deviceOpe.operation(getDevice, null).getJSONObject("data");
            JSONArray devices = data.getJSONArray("devices");
            List<Device> list = new ArrayList<Device>();
            for (int i=0;i<devices.size();i++){
                JSONObject jsonObject = devices.getJSONObject(i);
                Device device =  JSONOneNet2DeviceUtil.getDeviceFrom(jsonObject);
                list.add(device);
            }

            if(list.size()>0){
                devicelist.addAll(list);
                long total_count = data.getLongValue("total_count");
                long pagenow = data.getLongValue("page");

                if(pagenow>=total_count){
                    flag_end = true;
                }else{
                    page++;
                }
            }else{
                flag_end = true;
            }


        }

        List<Device>  list = deviceService.getDeviceListByProductId(Const.ONENET_PRODUCT_ID);
        List<Device> aja = new ArrayList<>();
        for (int i=0;i<list.size();i++){
            Device da = list.get(i);
            boolean flag_has = false;
            for(Device device:devicelist){
                if(da.getDeviceId().equals(device.getDeviceId())){
                    flag_has = true;
                    break;
                }
            }
            if(!flag_has){
                aja.add(da);
            }
        }

        List<Device> aja2 = new ArrayList<>();
        for (int i=0;i<devicelist.size();i++){
            Device da = devicelist.get(i);
            boolean flag_has = false;
            for(Device device:list){
                if(da.getDeviceId().equals(device.getDeviceId())){
                    flag_has = true;
                    break;
                }
            }
            if(!flag_has){
                aja2.add(da);
            }
        }

        deviceService.setDevicesUpdate(aja,devicelist);

        ParameterMap data = new ParameterMap();
        data.put("add",aja2);
        data.put("delete",aja);

        return ResponseModel.getModel(ResultEnum.SUCCESS, data);



    }


    /**
     * 同步设备数据event到mongodb（NBIOT中移物联平台）
     * @return
     */
    @RequestMapping(value="/deviceData",method= RequestMethod.GET)
    @ResponseBody
    public Object getDeviceData(){
        Calendar now = Calendar.getInstance();
        now.add(Calendar.YEAR, -1);
        long start_time_long = now.getTime().getTime();
        String date = sdfTime.format(new Date(start_time_long));
        date = date.replace(" ","T");
        List<Device> list = deviceService.getDeviceListByProductId(Const.ONENET_PRODUCT_ID);

        for(int i=0;i<list.size();i++){
          Device device  = list.get(i);
          String device_id =  device.getDeviceId();
          String cursor ="";
          boolean flag_end = false;
            GetDeviceDataOpe getDeviceDataOpe = new GetDeviceDataOpe(Const.APIKEY);
            GetDeviceData getDeviceData = new GetDeviceData(date,cursor,device_id);
          while (!flag_end){
              JSONObject jsonObject = getDeviceDataOpe.operation(getDeviceData,null);
              long errno = jsonObject.getLongValue("errno");
              if(errno==0){
                  JSONObject jsonObjectData = jsonObject.getJSONObject("data");
                  JSONArray datastreams = jsonObjectData.getJSONArray("datastreams");
                  if(datastreams.size()>0){
                      JSONObject job = datastreams.getJSONObject(0);
                      JSONArray datas = job.getJSONArray("datapoints");
                      List<OnetEvent> onetEventList = new ArrayList<>();
                      for(int j=0;j<datas.size();j++){
                          JSONObject jsonObject1 = datas.getJSONObject(j);
                          String at = jsonObject1.getString("at");
                          long event_time = DateUtil.getTimeMsLong(at);
                          try {
                              String event_content =  getEventContent(jsonObject1.getJSONArray("value"));
                              OnetEvent onetEvent = new OnetEvent();
                              onetEvent.setDeviceId(device_id);
                              onetEvent.setEventContent(event_content);
                              onetEvent.setCreateTime(event_time);
                              onetEventList.add(onetEvent);
                          }catch (Exception e){
                              e.printStackTrace();
                          }


                      }
                      if(onetEventList.size()>0)
                      devOneNetLogService.addEvent(onetEventList);
                      if (jsonObjectData.containsKey("cursor")){
                          cursor =  jsonObjectData.getString("cursor");
                          getDeviceData.setCursor(cursor);
                      }else{
                          flag_end = true;
                      }
                  }else{
                      flag_end = true;
                  }


              }else{
                  flag_end = true;
              }
          }


        }

        return ResponseModel.getModel(ResultEnum.SUCCESS, null);
    }


    String getEventContent(JSONArray jsonArray){

        StringBuilder ur = new StringBuilder();
        for(int i=0;i<jsonArray.size();i++){
            long b = jsonArray.getByteValue(i);
            if(b<0) b = 256+b;
            String a = String.format("%02x",b);
            ur.append(a.toUpperCase());
        }

        return ur.toString();
    }
}
